package com.miyake.client.datamanage;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.miyake.client.DataService;
import com.miyake.client.tools.ClickableLabel;
import com.miyake.client.tools.OkCancelDialog;
import com.miyake.client.tools.ShowDialog;
import com.miyake.client.tools.SmallButton;
import com.miyake.client.tools.WaitPopup;

public class ShowChildList2 {
	private NodeProperty node;
	private VerticalPanel panel;
	private int type = -1;
	private int depth = 10;
	private NodeUpdateHandler updateHandler;
	private int LABEL_COLUMN = 0;
	private int CHECKBOX_COLUMN = 1;
	private VerticalPanel overlayPanel;
	private Grid grid = new Grid();
	
	public ShowChildList2(NodeProperty node, VerticalPanel panel, NodeUpdateHandler updateHandler) {
		this.node = node;
		this.panel = panel;
		this.updateHandler = updateHandler;
	}

	public void show() {
		final ListBox combo = new ListBox();
		combo.addItem("All");
		combo.addItem("Chart");
		combo.addItem("Table");
		combo.addItem("Image");
		combo.addItem("Data");
//		combo.addItem("Folder"); 
		
		HorizontalPanel bar = new HorizontalPanel();
		panel.add(bar);
		bar.add(combo);
		bar.add(new SmallButton("Summary", new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				showSummary();
			}
		}));
		
		SmallButton overlayButton = new SmallButton("Overlay");
		bar.add(overlayButton);
		overlayButton.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				if (overlayPanel == null) {
					overlayPanel = new VerticalPanel();
					panel.add(overlayPanel);
				}
				overlayPanel.clear();
				new OverlayPage(getSelectedNodes(), overlayPanel);
			}
		});
		bar.add(new SmallButton("Delete", new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				deleteSelected();
			}
		}));
		
		bar.add(new SmallButton("Parse File", new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				new ParseFile(getSelectedNodesKey()) {
					@Override
					protected void onParseFinish(String key) {
						updateHandler.onNodeChange(key);
					}
				};
			}
		}));

		bar.add(new SmallButton("Add Chart", new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				addChart(getSelectedNodes());
			}
		}));

		bar.add(new SmallButton("Analyze", new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				new DoAnalysis(getSelectedNodesKey(), 1, updateHandler);
			}
		}));
		
		initGrid();
		combo.addChangeHandler(new ChangeHandler() {
			@Override
			public void onChange(ChangeEvent event) {
				type = getNodeType(combo);
				initGrid();
				showItem(node, 0);
			}
		});
		
		
		panel.add(grid);
		showItem(node, 0);
	}

	protected void addChart(final List<NodeProperty> selectedNodes) {
		new ShowDialog() {

			@Override
			protected void onOK(String text) {
				WaitPopup.showPopup(selectedNodes.size());
				for (final NodeProperty node : selectedNodes) {
					DataService.Util.getInstance().createPlot(node.getName() + " - Chart", 
							node.getKey(), -1, 0, new AsyncCallback<String>() {

						@Override
						public void onFailure(Throwable caught) {
							Window.alert(caught.getMessage());
						}

						@Override
						public void onSuccess(String result) {
							WaitPopup.hidePopup();
							if (!WaitPopup.isPopupVisible()) {
								updateHandler.onNodeAdd(node.getKey());
							}
						}
						
					});
				}
			}

			@Override
			protected DialogBox getDialogBox() {
				return new PlotDialog() {
					@Override
					protected Integer getColumnCount() {
						return 1;
					}
					
				};
			}
			
		};
	}

	protected void deleteSelected() {
		
		new ShowDialog() {
			@Override
			protected void onOK(String text) {
				WaitPopup.showPopup();
				DataService.Util.getInstance().deleteNodes(getSelectedNodesKey(), new AsyncCallback<Void>() {
					@Override
					public void onFailure(Throwable caught) {
						Window.alert(caught.getMessage());
					}

					@Override
					public void onSuccess(Void result) {
						WaitPopup.hidePopup();
						updateHandler.onSubNodeChange(node.getKey());
					}	
				});
			}

			@Override
			protected DialogBox getDialogBox() {
				return new OkCancelDialog();
			}
			
		};
	}

	protected void showSummary() {
		grid.resizeColumns(3);
		
		PageFactory factory = new SummaryPageFactory(updateHandler);
		NodeProperty n;
		for (int row = 1; row < grid.getRowCount(); row++) {
			if (isRowSelected(row)) {
				n = getRowNodeProperty(row);
			}
			else {
				grid.setWidget(row, 2, null);
				continue;
			}
			VerticalPanel p = new VerticalPanel();
			grid.setWidget(row, 2, p);
			if (n.getType().equals(NodeProperty.PLOT)) {
				factory.createChart(n, p);
			}
			else if (n.getType().equals(NodeProperty.IMAGE)) {
				factory.createImage(n, p);
			}
			else if (n.getType().equals(NodeProperty.TABLE)) {
				factory.createTable(n, p);
			}
			else if (n.getType().equals(NodeProperty.TEXT)) {
				factory.createText(n, p);
			}
			else if (n.getType().equals(NodeProperty.DATA)) {
				factory.createData(n, p);
			}
		}
	
	}

	private NodeProperty getRowNodeProperty(int row) {
		return (NodeProperty)((ClickableLabel)grid.getWidget(row, LABEL_COLUMN)).getUserObject();
	}

	private boolean isRowSelected(int row) {
		return ((CheckBox)grid.getWidget(row, CHECKBOX_COLUMN)).getValue();
	}

	public List<NodeProperty> getSelectedNodes() {
		List<NodeProperty> ret = new ArrayList<NodeProperty>();
		for (int row = 1; row < grid.getRowCount(); row++) {
			if (((CheckBox)grid.getWidget(row, CHECKBOX_COLUMN)).getValue().equals(true)) {
				ret.add((NodeProperty)((ClickableLabel)grid.getWidget(row, LABEL_COLUMN)).getUserObject());
			}
		}
		return ret;
	}

	public List<String> getSelectedNodesKey() {
		List<String> ret = new ArrayList<String>();
		for (int row = 1; row < grid.getRowCount(); row++) {
			if (((CheckBox)grid.getWidget(row, CHECKBOX_COLUMN)).getValue().equals(true)) {
				ret.add(((NodeProperty)((ClickableLabel)grid.getWidget(row, LABEL_COLUMN)).getUserObject()).getKey());
			}
		}
		return ret;
	}
	
	protected void initGrid() {
		grid.setBorderWidth(1);
		grid.resize(1, 2);
		final CheckBox check = new CheckBox();
		grid.setWidget(0, CHECKBOX_COLUMN, check);
		check.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				for (int i = 1; i <= grid.getRowCount(); i++) {
					((CheckBox)grid.getWidget(i, CHECKBOX_COLUMN)).setValue(check.getValue());
				}
			}
		});
	}
	
	protected void showItem(NodeProperty node, Integer level) {
		if (level > depth) {
			return;
		}
		
		for (NodeProperty n : node.getChildren()) {
			
			if (type == n.getType() || type == -1) {
				grid.resizeRows(grid.getRowCount() + 1);
				grid.setWidget(grid.getRowCount() - 1, LABEL_COLUMN, createLabel(level, n));
				grid.setWidget(grid.getRowCount() - 1, CHECKBOX_COLUMN, new CheckBox());
			}
			showItem(n, level+1);
		}
	}

	protected ClickableLabel createLabel(Integer level, final NodeProperty n) {
		HorizontalPanel h = new HorizontalPanel();
		String s = "";
		for (int i = 0; i < level; i++) {
			s += ">";
		}
		
		h.add(new Label(s));
		ClickableLabel label = new ClickableLabel(n.getName(), new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				updateHandler.onNodeChange(n.getKey());
			}
		});
		label.setUserObject(n);
		h.add(label);
		return label;
	}

	public void setType(int type) {
		this.type = type;
	}

	public int getType() {
		return type;
	}

	public void setDepth(int depth) {
		this.depth = depth;
	}

	public int getDepth() {
		return depth;
	}

	protected int getNodeType(final ListBox combo) {
		int t = 0;
		if (combo.getSelectedIndex() == 0) {
			t = -1;
		}
		else if (combo.getSelectedIndex() == 1) {
			t = NodeProperty.PLOT;
		}
		else if (combo.getSelectedIndex() == 2) {
			t = NodeProperty.TABLE;
		}
		else if (combo.getSelectedIndex() == 3) {
			t = NodeProperty.IMAGE;
		}
		else if (combo.getSelectedIndex() == 4) {
			t = NodeProperty.DATA;
		}
		else if (combo.getSelectedIndex() == 5) {
			t = NodeProperty.FOLDER;
		}
		return t;
	}
}
